Save Trained estimator(with pickle)

머신 러닝 모델을 훈련하려면 많은 계산 비용이 든다.
파이썬 인터프리터(interpreter)를 종료하고 새로운 예측을 하거나 웹 애플리케이션을 재시작할 때 마다, 모델을 훈련시킬 수 없다.

파이썬의 pickle 모듈을 사용해서 학습된 모델을 재사용할 수 있다.
Pickle
https://docs.python.org/3.7/library/pickle.html
Pickle을 이용해서 파이썬 객체의 구조를 압축된 바이트코드(bytecode)로 직렬화하고 복원할 수 있다.
분류기의 현재 상태를 저장하고, 레이블이 없는 새로운 샘플을 분류할 때, 훈련 데이터에서 모델을 다시 훈련할 필요 없이
저장된 모델을 불러 다시 사용할 수 있다.
import pickle
import os
dest=os.path.join('/Users/csian/Desktop/CP/data_set', 'pkl_objects')
if not os.path.exists(dest):
os.makedirs(dest)
pickle.dump(stop, open(os.path.join(dest, 'stopwords.pkl'), 'wb'), protocol=4)
pickle.dump(clf, open(os.path.join(dest, 'classifier.pkl'), 'wb'), protocol=4)
하드디스크나 SSD에 있는 data_set 디렉토리 안에 pkl_objects 서브디렉토리를 만들고
직렬화된 파이썬 객체를 저장한다.
pickle의 dump 메소드를 이용해서 훈련된 로지스틴 회귀 모델뿐 아니라 NLTK(Natural Language ToolKit) 라이브러리의
불용어도 직렬화하여 저장한다.(이후 서버에 NLTK 라이브러리를 설치할 필요가 없음)

dump(대상 객체, 파이썬 객체가 저장될 파일 객체)

파이썬 3.4번전과 그 이상 버전이 아니라면 protocol=4보다 낮은 프로토콜 번호를 사용해야 한다.
stop

['i', 'me', 'my', 'myself', 'we', 'our', 'ours', 'ourselves', 'you', "you're", "you've", "you'll", "you'd", 'your', 'yours', 'yourself', 'yourselves', 'he', 'him', 'his', 'himself', 'she', "she's", 'her', 'hers', 'herself', 'it', "it's", 'its', 'itself', 'they', 'them', 'their', 'theirs', 'themselves', 'what', 'which', 'who', 'whom', 'this', 'that', "that'll", 'these', 'those', 'am', 'is', 'are', 'was', 'were', 'be', 'been', 'being', 'have', 'has', 'had', 'having', 'do', 'does', 'did', 'doing', 'a', 'an', 'the', 'and', 'but', 'if', 'or', 'because', 'as', 'until', 'while', 'of', 'at', 'by', 'for', 'with', 'about', 'against', 'between', 'into', 'through', 'during', 'before', 'after', 'above', 'below', 'to', 'from', 'up', 'down', 'in', 'out', 'on', 'off', 'over', 'under', 'again', 'further', 'then', 'once', 'here', 'there', 'when', 'where', 'why', 'how', 'all', 'any', 'both', 'each', 'few', 'more', 'most', 'other', 'some', 'such', 'no', 'nor', 'not', 'only', 'own', 'same', 'so', 'than', 'too', 'very', 's', 't', 'can', 'will', 'just', 'don', "don't", 'should', "should've", 'now', 'd', 'll', 'm', 'o', 're', 've', 'y', 'ain', 'aren', "aren't", 'couldn', "couldn't", 'didn', "didn't", 'doesn', "doesn't", 'hadn', "hadn't", 'hasn', "hasn't", 'haven', "haven't", 'isn', "isn't", 'ma', 'mightn', "mightn't", 'mustn', "mustn't", 'needn', "needn't", 'shan', "shan't", 'shouldn', "shouldn't", 'wasn', "wasn't", 'weren', "weren't", 'won', "won't", 'wouldn', "wouldn't"]

clf

SGDClassifier(loss='log', max_iter=1, random_state=1)

소스코드 실행시, 위의 stop, clf 객체과 파일로 직렬화하여 저장된다.
joblib
https://joblib.readthedocs.io
넘파일 배열의 경우 joblib 라이브러리로 직렬화하는 것이 더욱 효율적이다.
HashingVecorizer는 학습 과정이 없기 때문에 pickle 에 직렬화할 필요가 없다.
대신 현재 사용하고 있는 파이썬 세션에서 HasingVectorizer 객체를 import 할 수 있도록
파이썬 스크립트 생성
/Users/csian/Desktop/CP/data_set/vectorizer.py
from sklearn.feature_extraction.text import HashingVectorizer
import re
import os
import pickle
cur_dir=os.path.dirname(__file__)
stop=pickle.load(open(os.path.join(cur_dir, 'pkl_objects', 'stopwords.pkl'), 'rb'))
def tokenizer(text):
text=re.sub('<[^>]*>', '', text)
emoticons=re.findall('(?::|;|=)(?:-)?(?:\)|\(|D|P)', text.lower())
text=re.sub('[\W]+', ' ', text.lower())+' '.join(emoticons).replace('-', '')
tokenized=[w for w in text.split() if w not in stop]
return tokenized
vect=HashingVectorizer(decode_error='ignore', n_features=2**21, preprocessor=None, tokenizer=tokenizer)
and go back to Terminal
import pickle
import re
import os
from vectorizer import vect # vectorizer.py vect import
clf=pickle.load(open(os.path.join('pkl_objects','classifier.pkl'), 'rb'))
import numpy as np
label={0:'', 1:''}
example=['I love this movie']
X=vect.transform(example)
print(': %s\n: %.2f%%' %(label[clf.predict(X)[0]], np.max(clf.predict_proba(X))*100))

예측: 양성

확률: 90.37%

predict_proba 메서드는 고유한 클래스 레이블 각각에 대한 확률을 반환한다.
따라서 확률 값이 가장 큰 클래스 레이블이 predict 메서드에서 반환되는 클래스 레이블의 확률이다.
만일 모델이 복잡한 다중 클래스 환경이라면, 매핑 딕셔너리 또한 모델과 함께 저장되어야 한다.